package org.chipu.jnids.gui;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import javax.annotation.Nullable;
import org.chipu.jnids.beans.Profile;
import org.chipu.jnids.sce.profile.CombinedStats;
import org.chipu.jnids.sce.profile.StatType;
import org.chipu.jnids.sce.profile.Stats.Characteristic;
import org.chipu.shared.util.file.FileUtils;
import org.chipu.shared.util.singletons.LoggingUtils;
import org.chipu.shared.util.singletons.NetworkUtils;
import org.jfree.chart.*;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.DefaultXYDataset;

public final class ProfileCharts {
	public static void main(String[] args) throws IOException, Exception {
		Profile p = Profile.decode(FileUtils
			.readTextFile(new File("encoded_profile_files_complete_noip.xml")));
		StatType inType = StatType.getStatType(StatType.Type.CONNECTIONS_OUT);
		saveIntoProperFile(p, inType, Characteristic.AVERAGE);
		saveIntoProperFile(p, inType, Characteristic.STANDARDDEVIATION);
		saveIntoProperFile(p, inType, Characteristic.SKEWNESS);
		saveIntoProperFile(p, inType, Characteristic.KURTOSIS);

		saveIntoProperFile(p, new StatType(StatType.Type.CONNECTIONS_OUT_BY_PROTOCOL, NetworkUtils
			.getProtocolCode("tcp")), Characteristic.AVERAGE);
		saveIntoProperFile(p, new StatType(StatType.Type.CONNECTIONS_OUT_BY_PROTOCOL, NetworkUtils
			.getProtocolCode("udp")), Characteristic.AVERAGE);
		saveIntoProperFile(p, new StatType(StatType.Type.CONNECTIONS_OUT_BY_PROTOCOL, NetworkUtils
			.getProtocolCode("icmp")), Characteristic.AVERAGE);
	}

	private ProfileCharts() {/**/}

	public static void saveIntoProperFile(Profile p, StatType type, Characteristic c) throws IOException {
		JFreeChart chart = createChart(p, type, c);
		if (chart != null)
			ChartUtilities.saveChartAsJPEG(new File("chart_" + type + "_" + c + ".jpg"), chart, 800, 500);
	}

	@Nullable
	public static JFreeChart createChart(Profile p, StatType type, Characteristic c) {
		Map<Short, CombinedStats> stats = p.getStats(type);
		if (stats == null) {
			LoggingUtils.getLogger().warning("No stats for " + type + ", " + c);
			return null;
		}

		DefaultXYDataset dataset = new DefaultXYDataset();
		double[][] d = new double[2][24 * 7];
		for(int i = 0; i < d[0].length; i++)
			d[0][i] = i;
		for(Map.Entry<Short, CombinedStats> e : stats.entrySet()) {
			int s = convert(e.getKey());
			d[0][s] = s;
			d[1][s] = e.getValue().getStats().getValue(c);
			if (Double.isInfinite(d[1][s]))
				d[1][s] = d[1][s] > 0? Double.MAX_VALUE: Double.MIN_VALUE;
		}
		if (c == Characteristic.SKEWNESS)
			System.err.println("--  " + Arrays.toString(d[1]));
		dataset.addSeries("-", d);

		// XYSeries series = new XYSeries("XYGraph");
		// for(Map.Entry<Short, CombinedStats> e : stats.entrySet()) {
		// int s = convert(Profile.getDayOfWeekForId(e.getKey()), Profile.getHourOfDayForId(e.getKey()));
		// series.add(s, e.getValue().getStats().getValue(c));
		// }
		// XYSeriesCollection dataset = new XYSeriesCollection();
		// dataset.addSeries(series);

		return ChartFactory.createXYLineChart(p.getName() + ": " + type, "hours", c.toString(), dataset,
			PlotOrientation.VERTICAL, false, false, false);
	}

	private static int convert(short id) {
		// MON..SUN (0..6)
		int day = Profile.getDayOfWeekForId(id) - 2;
		if (day < 0)
			day += 7;
		int hour = Profile.getHourOfDayForId(id);
		return day * 24 + hour;
	}
}